www.gusucode.com > VC 编写的VC++工程清理工具-源码程序 > VC 编写的VC++工程清理工具-源码程序/code/CleanerDlg.cpp
// CleanerDlg.cpp : implementation file // Download by http://www.NewXing.com #include "stdafx.h" #include "VCProjectCleaner.h" #include "CleanerDlg.h" //#include "StatLink.h" #include <mmsystem.h> #pragma comment(lib,"winmm.lib") #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif BOOL DeleteDirectory(CString DirName); // I used two global functions, it's not good, right? CString GetFileExt(CString filename, CString filetitle); BOOL DeleteCertainFile(CString targetDirectory,/* LPCTSTR type1, LPCTSTR type2,*/ int* deleteNum); //And now I add a new one. just to handle the VS projects. ///////////////////////////////////////////////////////////////////////////// // CAboutDlg dialog used for App About CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD) { //{{AFX_DATA_INIT(CAboutDlg) //}}AFX_DATA_INIT } void CAboutDlg::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CAboutDlg) //}}AFX_DATA_MAP } BOOL CAboutDlg::OnInitDialog() { CDialog::OnInitDialog(); // TODO: Add extra initialization here m_wndLink1.m_link = _T("tencent://message/?uin=137571735"); m_wndLink2.m_link = _T("mailto:lusta@live.cn"); m_wndLink3.m_link = _T("http://hi.baidu.com/lustaone/"); m_wndLink4.m_link = _T("http://hi.baidu.com/lustaone/"); m_wndLink1.SubclassDlgItem(IDC_STATIC_QQ, this); m_wndLink2.SubclassDlgItem(IDC_STATIC_EMAIL, this); m_wndLink3.SubclassDlgItem(IDC_STATIC_SPACE, this); m_wndLink4.SubclassDlgItem(IDC_STATIC_PHOTO, this); return TRUE; // return TRUE unless you set the focus to a control // EXCEPTION: OCX Property Pages should return FALSE } BEGIN_MESSAGE_MAP(CAboutDlg, CDialog) //{{AFX_MSG_MAP(CAboutDlg) //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CMyDlg dialog CMyDlg::CMyDlg(CWnd* pParent /*=NULL*/) : CDialog(CMyDlg::IDD, pParent) { //{{AFX_DATA_INIT(CMyDlg) //}}AFX_DATA_INIT m_hIcon = AfxGetApp()->LoadIcon(IDI_ROBOT); // m_lDeleteList.RemoveAll(); } void CMyDlg::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CMyDlg) DDX_Control(pDX, IDC_LIST, m_ListCtrl); //}}AFX_DATA_MAP } BEGIN_MESSAGE_MAP(CMyDlg, CDialog) //{{AFX_MSG_MAP(CMyDlg) ON_WM_SYSCOMMAND() ON_WM_PAINT() ON_WM_QUERYDRAGICON() ON_NOTIFY(TVN_ITEMEXPANDING, IDC_TREE, OnItemExpandingBrowseTree) ON_NOTIFY(NM_RCLICK, IDC_TREE, OnRClickBrowseTree) ON_NOTIFY(TVN_DELETEITEM, IDC_TREE, OnDeleteItemBrowseTree) ON_NOTIFY(TVN_SELCHANGED, IDC_TREE, OnSelChangedBrowseTree) ON_BN_CLICKED(ID_EXECUTE, OnExecute) ON_WM_CLOSE() ON_WM_DESTROY() //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CMyDlg message handlers BOOL CMyDlg::OnInitDialog() { CDialog::OnInitDialog(); // Add "About..." menu item to system menu. // IDM_ABOUTBOX must be in the system command range. ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX); ASSERT(IDM_ABOUTBOX < 0xF000); CMenu* pSysMenu = GetSystemMenu(FALSE); if (pSysMenu != NULL) { CString strAboutMenu; strAboutMenu.LoadString(IDS_ABOUTBOX); if (!strAboutMenu.IsEmpty()) { pSysMenu->AppendMenu(MF_SEPARATOR); pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu); } } SetIcon(m_hIcon, TRUE); // Set big icon SetIcon(m_hIcon, FALSE); // Set small icon // TODO: Add extra initialization here // m_ImageList = new CImageList(); // m_ImageList->Add(AfxGetApp()->LoadIcon(IDR_MAINFRAME)); m_TreeCtrl = (CShellTree*)GetDlgItem(IDC_TREE); m_TreeCtrl->EnableImages(); m_TreeCtrl->PopulateTree(); // m_ListCtrl.SetImageList(m_ImageList, LVSIL_NORMAL | LVSIL_SMALL | LVSIL_STATE); CheckRadioButton(IDC_RADIO_DEFAULT,IDC_RADIO_CUSTOM,IDC_RADIO_DEFAULT); return TRUE; // return TRUE unless you set the focus to a control } void CMyDlg::OnSysCommand(UINT nID, LPARAM lParam) { if ((nID & 0xFFF0) == IDM_ABOUTBOX) { CAboutDlg dlgAbout; dlgAbout.DoModal(); } else { CDialog::OnSysCommand(nID, lParam); } } // If you add a minimize button to your dialog, you will need the code below // to draw the icon. For MFC applications using the document/view model, // this is automatically done for you by the framework. void CMyDlg::OnPaint() { if (IsIconic()) { CPaintDC dc(this); // device context for painting SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0); // Center icon in client rectangle int cxIcon = GetSystemMetrics(SM_CXICON); int cyIcon = GetSystemMetrics(SM_CYICON); CRect rect; GetClientRect(&rect); int x = (rect.Width() - cxIcon + 1) / 2; int y = (rect.Height() - cyIcon + 1) / 2; // Draw the icon dc.DrawIcon(x, y, m_hIcon); } else { CDialog::OnPaint(); } } HCURSOR CMyDlg::OnQueryDragIcon() { return (HCURSOR) m_hIcon; } void CMyDlg::OnItemExpandingBrowseTree(NMHDR* pNMHDR, LRESULT* pResult) { NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR; // TODO: Add your control notification handler code here PlaySound(MAKEINTRESOURCE(IDR_WAVE_MINIMIZE),AfxGetResourceHandle(),SND_ASYNC|SND_RESOURCE); m_TreeCtrl->OnFolderExpanding(pNMHDR,pResult); *pResult = 0; } void CMyDlg::OnSelChangedBrowseTree(NMHDR* pNMHDR, LRESULT* pResult) { NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR; // TODO: Add your control notification handler code here // m_TreeCtrl->PopulateTree(); //加了这句就陷入死循环...I know... CString szPath; if(m_TreeCtrl->OnFolderSelected(pNMHDR,pResult,szPath)) { /* // m_FileListCtl.SetWindowText(szPath); // MessageBox(szPath); m_sProjectDirectory = szPath; ((CListCtrl*)(GetDlgItem(IDC_LIST)))->DeleteAllItems(); // ((CListCtrl*)(GetDlgItem(IDC_LIST)))->SetTextColor(RGB(128,255,255)); // m_ImageList.DeleteImageList(); CFileFind cff; CString str = ""; int i = 0; BOOL bWorking = cff.FindFile(szPath+"\\*.*"); while (bWorking) { bWorking = cff.FindNextFile(); str = (LPCTSTR) cff.GetFileName(); if(str == "." || str == ".." ) continue; //得到图标,添加到m_ImageList // if (str.Find(".") == -1) // { // continue; // } // if (str.Right(3) != "rar") // { // continue; // } // SHFILEINFO shfi; // SHGetFileInfo(cff.GetFilePath(),NULL,&shfi,sizeof(SHFILEINFO),SHGFI_ICON|SHGFI_LARGEICON); // m_ImageList.Add(shfi.hIcon); ((CListCtrl*)(GetDlgItem(IDC_LIST)))->InsertItem(i++,str,1); // ((CListCtrl*)(GetDlgItem(IDC_LIST)))->SetCheck(i++,TRUE); // str += "\n"; } cff.Close(); // MessageBox(str); */ // Above is the old version of the code which fill the CListCtrl. // Now I have made a new function to do the job, all it needs is a parameter of CString type // that indicates the target directory. PlaySound(MAKEINTRESOURCE(IDR_WAVE_MINIMIZE),AfxGetResourceHandle(),SND_ASYNC|SND_RESOURCE); m_sProjectDirectory = szPath; RefreshListCtrl(szPath); } *pResult = 0; } void CMyDlg::OnRClickBrowseTree(NMHDR* pNMHDR, LRESULT* pResult) { // TODO: Add your control notification handler code here m_TreeCtrl->GetContextMenu(pNMHDR,pResult); *pResult = 0; } void CMyDlg::OnDeleteItemBrowseTree(NMHDR* pNMHDR, LRESULT* pResult) { NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR; // TODO: Add your control notification handler code here m_TreeCtrl->OnDeleteShellItem(pNMHDR,pResult); *pResult = 0; } void CMyDlg::OnExecute() { ShakeYourAss(); BeginWaitCursor(); if (((CButton*)(GetDlgItem(IDC_RADIO_DEFAULT)))->GetCheck()) { // MessageBox("Default Option!"); CFileFind cff; CString str = ""; CString deleteResult; int deleteNum = 0; BOOL bWorking = cff.FindFile(m_sProjectDirectory+"\\*.*"); while (bWorking) { bWorking = cff.FindNextFile(); if (cff.IsDots()) continue; str = (LPCTSTR) cff.GetFileName(); str.MakeLower(); //得到图标,添加到m_ImageList, but the question is that I don't know how to get the target ICON... // SHFILEINFO shfi; // SHGetFileInfo(cff.GetFilePath(),NULL,&shfi,sizeof(SHFILEINFO),SHGFI_ICON|SHGFI_LARGEICON); // m_ImageList.Add(shfi.hIcon);//wrong..wrong...wrong......I just wanna suicide // ((CListCtrl*)(GetDlgItem(IDC_LIST)))->SetCheck(i++,TRUE); // str += "\n"; // if(str == "." || str == ".." )//these two IF statements have the same meaning, either is OK // continue; // if (cff.IsDirectory() && (str == "debug" || str == "release")) // { // if(::DeleteDirectory(cff.GetFilePath())) // deleteNum++; // continue; // } if (cff.IsDirectory()) { if (str == "debug" || str == "release") { if(::DeleteDirectory(cff.GetFilePath())) deleteNum++; continue; } else// Here "str" should be the project name. {//For projects made by VS20XX version, because they have different project structure, // we have to get into the ../projectname/projectname/ and delete 2 types of files: *.aps *.user CString targetDir = m_sProjectDirectory+"\\"+str; ::DeleteCertainFile(targetDir,/*".aps",".user",*/ &deleteNum); continue; } } CString ext = ::GetFileExt(cff.GetFileName(),cff.GetFileTitle()); if (ext == ".aps"|| ext == ".opt" || ext == ".plg" || ext == ".ncb" || ext == ".suo") { if (::DeleteFile(cff.GetFilePath())) deleteNum++; } m_lDeleteList.AddHead(cff.GetFilePath()); //Determine whether the file is one of the target format, if is, add its Path+Name to the List } cff.Close(); // POSITION position; // position = m_lDeleteList.GetHeadPosition(); // while(position) // { // AfxMessageBox(m_lDeleteList.GetAt(position)); // if(::DeleteDirectory(m_lDeleteList.GetNext(position))) // deleteNum++; // } deleteResult.Format("%d files or directories have been deleted!", deleteNum); MessageBox(deleteResult,"Deletion Result",MB_OK|MB_SETFOREGROUND|MB_ICONINFORMATION); } else { MessageBox("Custom Option is under developing ~","Please Wait..."); } // m_TreeCtrl->PopulateTree(); // m_TreeCtrl->TunnelTree(m_sProjectDirectory); RefreshListCtrl(m_sProjectDirectory); EndWaitCursor(); } void CMyDlg::RefreshListCtrl(CString strProjectDirectory) { ((CListCtrl*)(GetDlgItem(IDC_LIST)))->DeleteAllItems(); // ((CListCtrl*)(GetDlgItem(IDC_LIST)))->SetTextColor(RGB(128,255,255)); CString str = ""; CFileFind cff; int i = 0; BOOL bWorking = cff.FindFile(strProjectDirectory+"\\*.*"); while (bWorking) { bWorking = cff.FindNextFile(); if (cff.IsDots()) continue; str = (LPCTSTR) cff.GetFileName(); ((CListCtrl*)(GetDlgItem(IDC_LIST)))->InsertItem(i++,str); } cff.Close(); } void CMyDlg::OnClose() { // TODO: Add your message handler code here and/or call default // if (m_ImageList) // { // delete []m_ImageList; // } CDialog::OnClose(); } BOOL DeleteDirectory(CString DirName) { // CString log = ""; CFileFind tempFind; char tempFileFind[200]; sprintf(tempFileFind,"%s\\*.*",DirName); // AfxMessageBox(tempFileFind); BOOL IsFinded = (BOOL)tempFind.FindFile(tempFileFind); while(IsFinded) { IsFinded = (BOOL)tempFind.FindNextFile(); if (!tempFind.IsDots()) { char foundFileName[200]; strcpy(foundFileName,tempFind.GetFileName().GetBuffer(200)); if (tempFind.IsDirectory()) { char tempDir[200]; sprintf(tempDir,"%s\\%s",DirName,foundFileName); // log += tempDir; // log += "\n"; DeleteDirectory(tempDir); } else { char tempFileName[200]; sprintf(tempFileName,"%s\\%s",DirName,foundFileName); // log += tempFileName; // log += "\n"; DeleteFile(tempFileName); } } } tempFind.Close(); // MessageBox(NULL,log,"",MB_OK); if (!RemoveDirectory(DirName)) { // AfxMessageBox("Delete directory failed!"); return FALSE; } return TRUE; } CString GetFileExt(CString filename, CString filetitle) { filename.TrimLeft((LPCTSTR)filetitle); return filename; } BOOL DeleteCertainFile(CString targetDirectory, /*LPCTSTR type1, LPCTSTR type2,*/ int *deleteNum) { CFileFind cff; CString str; BOOL bWorking = cff.FindFile(targetDirectory+"\\*.*"); while(bWorking) { bWorking = cff.FindNextFile(); if (cff.IsDots()) continue; str = (LPCTSTR) cff.GetFileName(); str.MakeLower(); if (cff.IsDirectory()) { if (str == "debug" || str == "release") { if(::DeleteDirectory(cff.GetFilePath())) (*deleteNum)++; continue; } else //Directory of other names, "res", for example. We can't remove them. { continue; } } CFile tempFile(cff.GetFilePath(),CFile::modeRead); CString ext = ::GetFileExt(cff.GetFileName(),cff.GetFileTitle()); // CString ext = tempFile.GetFileExt();// wrong.. GetFileExt() is not a menber function of CFile... ext.MakeLower(); if (ext == ".aps"|| ext == ".user") { if (::DeleteFile(cff.GetFilePath())) (*deleteNum)++; } } return TRUE; } void CMyDlg::OnDestroy() { CDialog::OnDestroy(); // TODO: Add your message handler code here CAboutDlg dlg; dlg.DoModal(); } //总的来看,越写结构越混乱。尤其是要对VS20XX版本的工程起作用的话,后面加的一个全局函数完全是个无奈的悲剧。 //整个结构就……情何以堪了 //结构上要优化的话,用一个统一的递归可能结构上就清晰一点。不需要几个功能显得重复的函数。 void CMyDlg::ShakeYourAss() { PlaySound(MAKEINTRESOURCE(IDR_WAVE_SHAKE),AfxGetResourceHandle(),SND_ASYNC|SND_RESOURCE); CPoint CurrentPos; CRect rect; GetClientRect(&rect); ClientToScreen(&rect); CurrentPos.x = rect.left; CurrentPos.y = rect.top; int FrameWidth; int FrameHight; int CaptionHight; //我当前系统设置上这三个值分别为3,3,22 FrameWidth = GetSystemMetrics(SM_CXFIXEDFRAME); FrameHight = GetSystemMetrics(SM_CYFIXEDFRAME); CaptionHight = GetSystemMetrics(SM_CYCAPTION); //这里需要将CurrentPos坐标offset()到主窗口左上角坐标 CurrentPos.Offset(-FrameWidth, -CaptionHight-FrameHight); //实现抖动: 半个小圈 + 三个大圈 + 半个小圈 SetWindowPos(&wndTopMost,CurrentPos.x-1,CurrentPos.y-2,0,0, SWP_NOSIZE); Sleep(10);//上面的SWP_NOSIZE参数忽略cx,cy,故可置0 SetWindowPos(&wndTopMost,CurrentPos.x-4,CurrentPos.y-4,0,0, SWP_NOSIZE); Sleep(10); SetWindowPos(&wndTopMost,CurrentPos.x-7,CurrentPos.y-2,0,0, SWP_NOSIZE); Sleep(10); SetWindowPos(&wndTopMost,CurrentPos.x-8,CurrentPos.y,0,0, SWP_NOSIZE); Sleep(10); int i = 0; for (;i<3;i++) { SetWindowPos(&wndTopMost,CurrentPos.x-6,CurrentPos.y+6,0,0, SWP_NOSIZE); Sleep(10); SetWindowPos(&wndTopMost,CurrentPos.x,CurrentPos.y+8,0,0, SWP_NOSIZE); Sleep(10); SetWindowPos(&wndTopMost,CurrentPos.x+6,CurrentPos.y+6,0,0, SWP_NOSIZE); Sleep(10); SetWindowPos(&wndTopMost,CurrentPos.x+8,CurrentPos.y,0,0, SWP_NOSIZE); Sleep(10); SetWindowPos(&wndTopMost,CurrentPos.x+6,CurrentPos.y-6,0,0, SWP_NOSIZE); Sleep(10); SetWindowPos(&wndTopMost,CurrentPos.x,CurrentPos.y-8,0,0, SWP_NOSIZE); Sleep(10); SetWindowPos(&wndTopMost,CurrentPos.x-6,CurrentPos.y-6,0,0, SWP_NOSIZE); Sleep(10); SetWindowPos(&wndTopMost,CurrentPos.x-8,CurrentPos.y,0,0, SWP_NOSIZE); Sleep(10); } SetWindowPos(&wndTopMost,CurrentPos.x-7,CurrentPos.y+2,0,0, SWP_NOSIZE); Sleep(10); SetWindowPos(&wndTopMost,CurrentPos.x-4,CurrentPos.y+4,0,0, SWP_NOSIZE); Sleep(10); SetWindowPos(&wndTopMost,CurrentPos.x-1,CurrentPos.y+2,0,0, SWP_NOSIZE); Sleep(10); SetWindowPos(&wndTopMost,CurrentPos.x,CurrentPos.y,0,0, SWP_NOSIZE); }